home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #45 (Jun 89) / Forth Code / Beeper INIT next >
Text File  |  1989-04-17  |  5KB  |  201 lines

  1. \ INIT example which patches _GetResource 
  2. \ with a call to _Sysbeep if type=CODE id=0
  3. \ Also patches _ExitToShell, using an absolutely
  4. \ AWFUL hack, but a _SetTrapAddress patch
  5. \ seems to be removed under Multifinder
  6. \ J. Langowski / MacTutor April 1989
  7.  
  8. only forth also mac also assembler
  9.  
  10. ( *** compiler support words for external definitions *** )
  11. : :xdef 
  12.     create     -4 allot
  13.         $4EFA w, ( JMP )
  14.         0 w,     ( entry point to be filled later )
  15.         0 ,      ( length of routine to be filled later )
  16.         here 6 - 76543
  17. ;
  18.  
  19. : ;xdef { branch marker entry | -- }
  20.     marker 76543 <> abort" xdef mismatch"
  21.     entry branch - branch w!
  22.     here branch - 2+ branch 2+ !
  23.     
  24. : xlen 4 + @ ; ( get length word of external definition )
  25.  
  26. \ **** ext procedure glue macros
  27.  
  28. CODE ext.prelude
  29.     LINK    A6,#-700             ( 700 bytes of local Forth stack )
  30.     MOVEM.L A0-A5/D0-D7,-(A7)        ( save registers )
  31.     MOVE.L A6,A3                ( setup local loop return stack )
  32.     SUBA.L #500,A3                ( in the low 200 local stack bytes )
  33.     RTS            \ just to indicate the MACHro stops here 
  34. END-CODE MACH
  35.  
  36. CODE ext.epilogue
  37.     MOVEM.L (A7)+,A0-A5/D0-D7    ( restore registers )
  38.     UNLK    A6
  39.     RTS
  40. END-CODE MACH
  41.  
  42. .trap    _newPtr,SYS    $A51E
  43.  
  44. -4         CONSTANT     thePort
  45. $904     CONSTANT     CurrentA5
  46. $A9A0    CONSTANT    tGetRes    \ GetResource
  47. $A9F4    CONSTANT    tExit    \ ExitToShell
  48.  
  49. \ |--------------------------------|
  50. \ | INIT resource code starts here |
  51. \ |--------------------------------|
  52.  
  53. :xdef beeperINIT
  54.  
  55. header PatchStart
  56. header oldGetRes
  57.     DC.L 0
  58. header oldExit
  59.     DC.L 0
  60.  
  61. : GetResPatch
  62.     ext.prelude
  63.     CLR.L    D0
  64.     MOVE.W    8(A6),D0
  65.     MOVE.L    10(A6),D1
  66.     MOVE.L    D0,-(A6)
  67.     MOVE.L    D1,-(A6)
  68.  
  69. \ main FORTH code starts here
  70. \ this can be used to log any launch
  71. \ (i.e. GetResource CODE 0 ) to a log file
  72. \ which has to be created/opened by the INIT code
  73.  
  74.     ascii CODE = swap 0= and IF
  75.         \    (call) debugger
  76.             1 (call) sysbeep
  77.     THEN
  78. \ end of main code
  79.  
  80.     ext.epilogue
  81.     LEA        oldGetRes,A0
  82.     MOVE.L    (A0),A0
  83.     JMP        (A0) 
  84. ;
  85.  
  86. : ExitPatch
  87.     ext.prelude
  88.  
  89. \ main FORTH code starts here
  90. \ this can eventually be used to write a line to 
  91. \ the same log file as before
  92.     \        (call) debugger
  93.             1 (call) sysbeep
  94. \ end of main code
  95.  
  96.     ext.epilogue
  97.     LEA        oldExit,A0
  98.     MOVE.L    (A0),A0
  99.     JMP        (A0) 
  100. ;
  101.  
  102. header PatchEnd
  103.  
  104. : movePatch { | length -- patch }
  105.     ['] patchEnd ['] PatchStart -   -> length
  106.     length
  107.     MOVE.L (A6)+,D0
  108.     _newPtr,sys
  109.     MOVE.L A0,-(A6)
  110.     dup IF ( we have space in system heap )
  111.         ['] PatchStart over length swap (call) blockMove drop
  112.     THEN
  113. ;
  114.         
  115. : myINIT { | patch pExit -- }
  116.     movePatch -> patch
  117.     patch IF
  118.         \ patch _GetResource
  119.         tGetRes (call) GetTrapAddress
  120.         patch !        \  old GetResource
  121.         ['] GetResPatch ['] PatchStart -
  122.         patch + tGetRes (call) SetTrapAddress
  123.         " GetResource patch has been installed." 0 0 0 (call) ParamText
  124.         1000 0 (call) NoteAlert drop
  125.  
  126.         \ patch _ExitToShell, using hack
  127.         tExit (call) GetTrapAddress -> pExit
  128.         pExit w@ $4EF9 = 
  129.         IF \ is it a JMP ? we're probably in Multifinder...
  130.             pExit 2+ @
  131.             patch 4+ !    \  old ExitToShell
  132.             ['] ExitPatch ['] PatchStart -
  133.             patch + pExit 2+ ! 
  134.                 \ patch directly into Juggler's innards. BOO!
  135.             " ExitToShell patch in Multifinder." 0 0 0 (call) ParamText
  136.             1000 0 (call) NoteAlert drop
  137.         ELSE
  138.             pExit patch 4+ !
  139.             ['] ExitPatch ['] PatchStart -
  140.             patch + tExit (call) SetTrapAddress
  141.             " ExitToShell patch in Finder." 0 0 0 (call) ParamText
  142.             1000 0 (call) NoteAlert drop
  143.         THEN
  144.     ELSE
  145.         " Can't get memory for patches." 0 0 0 (call) ParamText
  146.         1000 0 (call) NoteAlert drop
  147.     THEN
  148. ;
  149.  
  150. : INITrun { | newA5 myGlobals [ 202 lallot ] theHandle -- } 
  151. \    (call) debugger 
  152.     ['] beeperINIT (call) recoverHandle -> theHandle
  153.     theHandle (call) Hlock drop
  154.     ^ newA5
  155.     MOVE.L    (A6)+,A5        \ create area for QD globals
  156.     MOVE.L    A5,CurrentA5    \ A5 points to it
  157.     ^ newA5 thePort + (call) InitGraf
  158.     (call) InitFonts
  159.     (call) InitWindows
  160.     (call) TEInit
  161.     0 (call) InitDialogs
  162.     (call) InitCursor
  163.  
  164.     myINIT    \ call main INIT routine
  165.  
  166.     theHandle (call) HUnLock drop
  167.     theHandle (call) DisposHandle drop
  168. ;
  169.  
  170. : gINIT
  171.     ext.prelude INITrun    ext.epilogue
  172.     MOVE.L    A5,CurrentA5    
  173. ;
  174.  
  175. ' gINIT ;xdef
  176.  
  177. ( *** creating the INIT file *** )
  178. : $create-res call CreateResFile call ResError L_ext ;
  179.  
  180. : $open-res { addr | refNum -- result }
  181.     addr call openresfile -> refNum
  182.     call ResError L_ext
  183.     dup not IF drop refNum THEN 
  184. ;
  185.  
  186. : $close-res call CloseResFile call ResError L_ext ;
  187.  
  188. : make-init { | refNum -- }
  189.     " theINIT" dup $create-res drop
  190.     $open-res dup -> refNum call UseResFile 
  191.     ascii INIT 12 call GetResource 
  192.         ?dup IF call RmveResource THEN
  193.     ['] beeperINIT dup xlen
  194.         call PtrToHand drop ( result code )
  195.         ascii INIT 12 call GetResource 
  196.             ?dup IF call RmveResource THEN
  197.         ascii INIT 12 " Beeper" call AddResource
  198.     refNum $close-res drop ( result code )
  199. ;
  200.